﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.Windows.Media;
using CAB=Microsoft.Practices.CompositeUI.Commands;
using WPF=System.Windows.Input;

namespace WPFCABShell.Shell.Interface.Services.Command
{
	/// <summary>
	/// Defines the functionality of a command service, which is responsible for creating and maintaining
	/// a registry of commands for the application.
	/// </summary>
	/// <remarks>
	/// <para>
	/// The command service is used in conjunction with other services such as the menu service. Commands are defined via
	/// the command service and then associated with UI elements via other services.
	/// </para>
	/// <para>
	/// Commands may either be registered or unregistered. Registered commands are exposed via the
	/// <see cref="RegisteredCommands"/> collection, and are intended to hold commands that may be useful for users to
	/// manipulate (eg. add to shortcuts or place them in tool bars). Registered commands can be assigned an ID, but
	/// unregistered commands are assigned a GUID by the service.
	/// </para>
	/// <para>
	/// Commands can wrap either CAB or WPF commands. This means that UI elements can invoke CAB or WPF commands. There is
	/// also the ability to wrap no command, which is useful for "container" items such as menu items that serve no purpose
	/// but to host child menu items.
	/// </para>
	/// </remarks>
	/// <threadsafety>
	/// Implementations of this interface are intended to be used from the UI thread only, and are therefore
	/// not thread safe.
	/// </threadsafety>
	public interface ICommandService
	{
		/// <summary>
		/// Gets a list of all registered commands.
		/// </summary>
		IList<ICommand> RegisteredCommands
		{
			get;
		}

		/// <summary>
		/// Occurs whenever a command is registered.
		/// </summary>
		event EventHandler<CommandEventArgs> CommandRegistered;

		/// <summary>
		/// Occurs whenever a command is executed.
		/// </summary>
		event EventHandler<CommandEventArgs> CommandExecuted;

		/// <summary>
		/// Occurs whenever a command is unregistered.
		/// </summary>
		event EventHandler<CommandEventArgs> CommandUnregistered;

		/// <summary>
		/// Creates an unregistered command that has no CAB or WPF command associated with it.
		/// </summary>
		/// <param name="name">
		/// The name of the command.
		/// </param>
		/// <param name="image">
		/// An optional image for the command.
		/// </param>
		/// <returns>
		/// The new command.
		/// </returns>
		ICommand CreateCommand(string name, ImageSource image);

		/// <summary>
		/// Creates an unregistered command that wraps a CAB command.
		/// </summary>
		/// <param name="command">
		/// The CAB command that the command wraps.
		/// </param>
		/// <param name="name">
		/// The name of the command.
		/// </param>
		/// <param name="image">
		/// An optional image for the command.
		/// </param>
		/// <returns>
		/// The new command.
		/// </returns>
		ICommand CreateCommand(CAB.Command command, string name, ImageSource image);

		/// <summary>
		/// Creates an unregistered command that wraps a WPF command.
		/// </summary>
		/// <param name="command">
		/// The WPF command that the command wraps.
		/// </param>
		/// <param name="name">
		/// The name of the command.
		/// </param>
		/// <param name="image">
		/// An optional image for the command.
		/// </param>
		/// <returns>
		/// The new command.
		/// </returns>
		ICommand CreateCommand(WPF.ICommand command, string name, ImageSource image);

		/// <summary>
		/// Creates and registers a command that wraps a CAB command.
		/// </summary>
		/// <param name="command">
		/// The CAB command that the command wraps.
		/// </param>
		/// <param name="id">
		/// The ID for the command.
		/// </param>
		/// <param name="category">
		/// A category for the command.
		/// </param>
		/// <param name="name">
		/// The name of the command.
		/// </param>
		/// <param name="image">
		/// An optional image for the command.
		/// </param>
		/// <returns>
		/// The new command.
		/// </returns>
		ICommand CreateAndRegisterCommand(CAB.Command command, string id, string category, string name, ImageSource image);

		/// <summary>
		/// Creates and registers a command that wraps a WPF command.
		/// </summary>
		/// <param name="command">
		/// The WPF command that the command wraps.
		/// </param>
		/// <param name="id">
		/// The ID for the command.
		/// </param>
		/// <param name="category">
		/// A category for the command.
		/// </param>
		/// <param name="name">
		/// The name of the command.
		/// </param>
		/// <param name="image">
		/// An optional image for the command.
		/// </param>
		/// <returns>
		/// The new command.
		/// </returns>
		ICommand CreateAndRegisterCommand(WPF.ICommand command, string id, string category, string name, ImageSource image);

		/// <summary>
		/// Unregisters the specified command.
		/// </summary>
		/// <param name="command">
		/// The command to unregister.
		/// </param>
		void UnregisterCommand(ICommand command);
	}
}
